<?php

declare(strict_types=1);

namespace App\Job;

use Hyperf\AsyncQueue\Job;
use App\Common\RedisCache;
use App\Exception\NullReturnException;
use App\Model\PlatformSetting;
use Hyperf\DbConnection\Db;
use Yurun\Util\HttpRequest;

class EcmpayPaymentJob extends Job
{
    public $params;

    public function __construct($params)
    {
        $this->params = $params;
    }

    public function handle()
    {
        $redisCache = new RedisCache();
        // 查询平台设置
        $platSetting = $redisCache->getPlatformSetting();
        // 查询用户代付设置
        $daifuSetting = $redisCache->getDaifuSettingByIdRealTime((int) $this->params['uid']);
        if ($daifuSetting['status'] == 2) {
            $this->notice('您的代付金额处于冻结状态，暂时无法进行支付操作。');
            throw new NullReturnException;
        } else if ($daifuSetting['status'] == -1) {
            $this->notice('您当前暂时无法使用代付功能。');
            throw new NullReturnException;
        }
        if ($platSetting['daifu_out_limit'] == 1) {
            $this->notice('单日最多可转100万元');
            throw new NullReturnException;
        }
        // 校验保证金机制
        if (!isset($daifuSetting['deposit_version_id']) || $daifuSetting['deposit_version_id'] == 0) {
            $this->notice('根据监管部门要求，使用本功能前需缴纳保证金，请先在“代付管理”-“代付设置“-“缴纳保证金”后使用，感谢您的支持');
            throw new NullReturnException;
        }
        $version = Db::table('dpay_deposit_version')->where('id', $daifuSetting['deposit_version_id'])->first();
        $depositInfo = Db::table('deposit')->where('uid', $this->params['uid'])->where('type', 2)->first();
        $version = json_decode(json_encode($version), true);
        $depositInfo = json_decode(json_encode($depositInfo), true);
        if (empty($version)) {
            $this->notice('保证金类别异常或非法，操作中断，如有疑问，可咨询平台客服');
            throw new NullReturnException;
        }
        if (empty($depositInfo)) {
            $this->notice('用户保证金类别异常或非法，操作中断，如有疑问，可咨询平台客服');
            throw new NullReturnException;
        }
        if ($version['money'] > $depositInfo['deposit']) {
            $this->notice('保证金不足，请续交保证金后使用，感谢您的支持');
            throw new NullReturnException;
        }
        // 支付总金额判断
        $where['uid'] = (int) $this->params['uid'];
        $todayStart = strtotime(date('Y-m-d'));
        $todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
        $where['create_time'] = ['between', [$todayStart, $todayEnd]];
        $where['status'] = 1;
        $total_today_pay_money = mongodb()->sum('df_trade_orders', 'money', $where);
        if ($version['limit'] < ($total_today_pay_money + $this->params['money'])) {
            $this->notice('当日代付总金额超过代付保证金对应限额，请调整代付保证金后重试');
            throw new NullReturnException;
        }
        // 计算代付服务费
        $daifuFee = 0;
        $add_feilv = 0;
        // 如果用户设置了费率增浮
        if (isset($this->params['daifu_fee_bili']) && $this->params['daifu_fee_bili'] > 0) {
            $add_feilv = $this->params['daifu_fee_bili'];
        }
        if ($this->params['uid'] != 1) {
            if ($this->params['rank'] == 1) {
                if ($platSetting['daifufree_feilv'] > 0) {
                    $daifuFee = round(($platSetting['daifufree_feilv'] + $add_feilv) * $this->params['money'] / 100, 2);
                    if ($daifuFee < 0.01) {
                        $daifuFee = 0.01;
                    }
                }
                $dailyLimit = (!empty($platSetting['daifu_free_limit'])) ? $platSetting['daifu_free_limit'] : 500;
            } else {
                if ($platSetting['daifufee_feilv'] > 0) {
                    $daifuFee = round(($platSetting['daifufee_feilv'] + $add_feilv) * $this->params['money'] / 100, 2);
                    if ($daifuFee < 0.01) {
                        $daifuFee = 0.01;
                    }
                }
                $dailyLimit = (!empty($platSetting['daifu_fee_limit'])) ? $platSetting['daifu_fee_limit'] : 500;
            }
        } else {
            $dailyLimit = 999999;
        }
        $this_money = round($this->params['money'] + $daifuFee, 2);
        $pay_yue = round($daifuSetting['daifu_money'] - $this_money, 2);
        if (empty($daifuSetting['daifu_money']) || ($pay_yue < $platSetting['daifu_baoliu'])) {
            $this->notice('代付余额(支付后余额)低于' . $platSetting['daifu_baoliu'] . '元将无法使用代付功能，请先登录会员中心进行充值');
            throw new NullReturnException;
        }
        // 支付总金额判断
        $where['uid'] = (int) $this->params['uid'];
        $todayStart = strtotime(date('Y-m-d'));
        $todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
        $where['create_time'] = ['between', [$todayStart, $todayEnd]];
        $where['status'] = 1;
        $total_today_pay_money = mongodb()->sum('df_trade_orders', 'money', $where);
        if ($daifuSetting['max_daily'] < ($total_today_pay_money + $this->params['money'])) {
            $this->notice('当日代付总金额超过您所设置的当日限额，本次代付失败');
            throw new NullReturnException;
        }
        if ($dailyLimit < ($total_today_pay_money + $this->params['money'])) {
            $this->notice('当日代付总金额超过平台系统限制，本次代付失败');
            throw new NullReturnException;
        }
        unset($where);
        // 支付总金额判断
        $where['uid'] = (int) $this->params['uid'];
        $todayStart = strtotime(date('Y-m-d'));
        $todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
        $where['create_time'] = ['between', [$todayStart, $todayEnd]];
        $where['alipay'] = $this->params['alipay'];
        $where['status'] = 1;
        $total_bishu = mongodb()->count('df_trade_orders', $where);
        if ($daifuSetting['bishu_daily'] <= $total_bishu) {
            $this->notice('该支付宝账户当日代付笔数超过系统当日笔数限额，本次代付失败');
            throw new NullReturnException;
        }
        // 代付支付宝每日限额判断
        $total_money = $redisCache->getDaifuTotalMoneyRealTime();
        if (!empty($platSetting['daifu_qiankuan']) && (round($total_money - $this_money, 2) < $platSetting['daifu_qiankuan'])) {
            (new \App\Service\ClearRedisCache())->clearPlatformSetting();
            $update['daifu_out_limit'] = 1;
            PlatformSetting::query()->where('id', 1)->update($update);
            unset($update);
            $msg = '单日最多可转100万元';
            $updatePayData['async_status'] = -1;
            $updatePayData['status'] = -1;
            $updatePayData['alipay_orderid'] = '';
            $updatePayData['daifu_fee'] = '';
            $updatePayData['daifued_yue'] = '';
            $updatePayData['statusmsg'] = $msg;
            mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
            if (!empty($daifuSetting['async_url'])) {
                $postData['thirdorder'] = $this->params['thirdorder'];
                $postData['orderId'] = $this->params['orderId'];
                $postData['alipay_orderid'] = '';
                $postData['reason'] = $msg;
                $postData['url'] = $daifuSetting['async_url'];
                queue_push(new PaymentResultNoticeJob($postData));
            }
            throw new NullReturnException;
        }
        // 查询支付配置
        if (!empty($daifuSetting['daifuer']) && ($daifuSetting['daifuer_status'] == 2)) {
            $daifuEr = $daifuSetting['daifuer'];
        } else {
            $daifuEr = $this->platformSetting['daifuer'];
        }
        $apiUrl = 'http://openapi.ecmpay.cn/alipay/transferAlipay';
        $postEcmData['app_id'] = '4687869497350654'; //应用APPID
        $postEcmData['auth_app_id'] = '2018112462287537'; //授权的支付宝应用APPID
        $postEcmData['trade_no'] = $this->params['orderId'];
        $postEcmData['trans_amount'] = $this->params['money'];
        $postEcmData['order_title'] = $daifuEr;
        $postEcmData['payer_show_name'] = $daifuEr;
        $postEcmData['identity'] = $this->params['alipay'];
        $postEcmData['name'] = $this->params['realname'];
        $postEcmData['remark'] = $this->params['beizhu'];
        $postEcmData['identity_type'] = 'ALIPAY_LOGON_ID';
        $postEcmData['sign'] = $this->createSign($postEcmData);
        $http = new HttpRequest;
        $http->timeout(8000);
        Db::beginTransaction();
        $feeStatus = Db::table('daifu_setting')->where('uid', $this->params['uid'])->decrement('daifu_money', $this_money);
        $daifuSetting = $redisCache->getDaifuSettingByIdRealTime((int) $this->params['uid']);
        if ($daifuSetting['daifu_money'] <= $platSetting['daifu_baoliu']) {
            Db::rollBack();
            $msg = '代付余额(支付后余额)低于' . $platSetting['daifu_baoliu'] . '元将无法使用代付功能，请先登录会员中心进行充值';
            $updatePayData['status'] = -1;
            $updatePayData['statusmsg'] = $msg;
            $updatePayData['daifued_yue'] = $pay_yue;
            mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
            if (!empty($daifuSetting['async_url'])) {
                // $postData['event'] = 'PAYMENT_FAIL';
                $postData['thirdorder'] = $this->params['thirdorder'];
                $postData['orderId'] = $this->params['orderId'];
                $postData['alipay_orderid'] = '';
                $postData['reason'] = $msg;
                $postData['url'] = $daifuSetting['async_url'];
                queue_push(new PaymentResultNoticeJob($postData));
            }
            throw new NullReturnException;
        }
        $response = $http->post($apiUrl, $postEcmData);
        $result = json_decode($response->body(),true);
        if (!empty($result) && $result['code'] == 200) {
            Db::commit();
            $order_id = $result['data']['order_id'];
            $updatePayData['alipay_orderid'] = $order_id;
            $updatePayData['status'] = 1;
            $updatePayData['daifued_yue'] = $pay_yue;
            $updatePayData['daifu_fee'] = round($daifuFee, 2);
            mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
            if (!empty($daifuSetting['async_url'])) {
                $postData['result'] = 'ok';
                $postData['thirdorder'] = $this->params['thirdorder'];
                $postData['orderId'] = $this->params['orderId'];
                $postData['alipay_orderid'] = $order_id;
                $postData['reason'] = 'success';
                $postData['url'] = $daifuSetting['async_url'];
                queue_push(new PaymentResultNoticeJob($postData));
            }
            $logData['title'] = '代付功能(平台)';
            $logData['uid'] = (int) $this->params['uid'];
            $logData['ip'] = $this->params['ip'];
            $logData['username'] = $this->params['username'];
            $logData['opstatus'] = $feeStatus;
            $feeStatus = ($feeStatus == 1) ? '成功' : '失败';
            $logData['extlog'] = '通过代付API提交了' . $this->params['money'] . '元代付，支付后余额：' . round($pay_yue, 2) . '元，收款人：' . $this->params['realname'] . '(' . $this->params['alipay'] . ')，手续费：' . $daifuFee . '元，支付宝流水号：' . $order_id . '，扣款状态：' . $feeStatus;
            addOperateLog($logData);
        } else {
            Db::rollBack();
            $updatePayData['status'] = -1;
            $updatePayData['daifued_yue'] = $pay_yue;
            $updatePayData['statusmsg'] = $result['msg'];
            mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
            if (!empty($daifuSetting['async_url'])) {
                $postData['thirdorder'] = $this->params['thirdorder'];
                $postData['orderId'] = $this->params['orderId'];
                $postData['alipay_orderid'] = '';
                $postData['reason'] = $updatePayData['statusmsg'];
                $postData['url'] = $daifuSetting['async_url'];
                queue_push(new PaymentResultNoticeJob($postData));
            }
            $msg = '代付失败，请检查传入数据是否正确: ' . json_encode($result, JSON_UNESCAPED_UNICODE);
            $logData['title'] = '代付功能(平台)';
            $logData['uid'] = (int) $this->params['uid'];
            $logData['ip'] = $this->params['ip'];
            $logData['username'] = $this->params['username'];
            $logData['extlog'] = '通过代付API提交了' . $this->params['money'] . '元代付，收款人：' . $this->params['realname'] . '(' . $this->params['alipay'] . ')，手续费：' . $daifuFee . '元，失败日志：' . json_encode($result, JSON_UNESCAPED_UNICODE);
            addOperateLog($logData);
        }
    }
    public function notice($msg)
    {
        $cacheData['async_status'] = -1;
        $cacheData['status'] = -1;
        $cacheData['statusmsg'] = $msg;
        $cacheData['alipay_orderid'] = '';
        $cacheData['daifu_fee'] = '';
        $cacheData['daifued_yue'] = '';
        mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $cacheData);
        if (!empty($daifuSetting['async_url'])) {
            // $postData['event'] = 'PAYMENT_FAIL';
            $postData['thirdorder'] = $this->params['thirdorder'];
            $postData['orderId'] = $this->params['orderId'];
            $postData['alipay_orderid'] = '';
            $postData['reason'] = $cacheData['statusmsg'];
            $postData['url'] = $daifuSetting['async_url'];
            queue_push(new PaymentResultNoticeJob($postData));
        }
        throw new NullReturnException;
    }
    public function createSign($param)
    {
        $secret = 'bcf36581c7542330a402de5e4a734d7d6ff4d1b2653c5e578a17fb8b4d594106';
        if (is_array($param)) {
            unset($param['sign']);
            foreach ($param as $k => $v) {
                if (!empty($v)) {
                    $Parameters[$k] = $v;
                }
            }
            unset($param, $k, $v);
            // 签名步骤一：按字典序排序参数
            ksort($Parameters);
            $buff = '';
            foreach ($Parameters as $k => $v) {
                $buff .= $k . $v;
            }
            unset($Parameters, $k, $v);
            $buff = $secret . $buff . $secret;
            $sign = strtoupper(md5($buff));
            unset($buff, $appInfo);
            return $sign;
        }
    }
}
